﻿using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.Drawing;

public partial class ValidImg : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request["Type"] != null)
        {
            string text = "";
            Random rnd = new Random();
            int code = rnd.Next(20);
            ShowValidationCode(ref code, out text, 4, 15, 10, RandomStringMode.Digital, Color.FromArgb(70, 130, 180));
        }
    }

    #region RandomStringMode
    public enum RandomStringMode
    {
        /// <summary>
        /// 小写字母
        /// </summary>
        LowerLetter,

        /// <summary>
        /// 大写字母
        /// </summary>
        UpperLetter,

        /// <summary>
        /// 混合大小写字母
        /// </summary>
        Letter,

        /// <summary>
        /// 数字
        /// </summary>
        Digital,

        /// <summary>
        /// 混合数字与大小字母
        /// </summary>
        Mix
    }
    #endregion

    #region GenerateRandomString
    private string GenerateRandomString(int length, RandomStringMode mode)
    {
        string rndStr = string.Empty;
        if (length == 0)
            return rndStr;

        char[] digitals = new char[10] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        char[] lowerLetters = new char[26] {
                'a', 'b', 'c', 'd', 'e', 'f', 'g',
                'h', 'i', 'j', 'k', 'l', 'm', 'n',
                'o', 'p', 'q', 'r', 's', 't',
                'u', 'v', 'w', 'x', 'y', 'z' };
        char[] upperLetters = new char[26] {
                'A', 'B', 'C', 'D', 'E', 'F', 'G',
                'H', 'I', 'J', 'K', 'L', 'M', 'N',
                'O', 'P', 'Q', 'R', 'S', 'T',
                'U', 'V', 'W', 'X', 'Y', 'Z' };
        char[] letters = new char[52]{
                'a', 'b', 'c', 'd', 'e', 'f', 'g',
                'h', 'i', 'j', 'k', 'l', 'm', 'n',
                'o', 'p', 'q', 'r', 's', 't',
                'u', 'v', 'w', 'x', 'y', 'z',
                'A', 'B', 'C', 'D', 'E', 'F', 'G',
                'H', 'I', 'J', 'K', 'L', 'M', 'N',
                'O', 'P', 'Q', 'R', 'S', 'T',
                'U', 'V', 'W', 'X', 'Y', 'Z' };
        char[] mix = new char[62]{
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f', 'g',
                'h', 'i', 'j', 'k', 'l', 'm', 'n',
                'o', 'p', 'q', 'r', 's', 't',
                'u', 'v', 'w', 'x', 'y', 'z',
                'A', 'B', 'C', 'D', 'E', 'F', 'G',
                'H', 'I', 'J', 'K', 'L', 'M', 'N',
                'O', 'P', 'Q', 'R', 'S', 'T',
                'U', 'V', 'W', 'X', 'Y', 'Z' };

        int[] range = new int[2] { 0, 0 };
        Random random = new Random();

        switch (mode)
        {
            case RandomStringMode.Digital:
                for (int i = 0; i < length; ++i)
                    rndStr += digitals[random.Next(0, digitals.Length)];
                break;

            case RandomStringMode.LowerLetter:
                for (int i = 0; i < length; ++i)
                    rndStr += lowerLetters[random.Next(0, lowerLetters.Length)];
                break;

            case RandomStringMode.UpperLetter:
                for (int i = 0; i < length; ++i)
                    rndStr += upperLetters[random.Next(0, upperLetters.Length)];
                break;

            case RandomStringMode.Letter:
                for (int i = 0; i < length; ++i)
                    rndStr += letters[random.Next(0, letters.Length)];
                break;

            default:
                for (int i = 0; i < length; ++i)
                    rndStr += mix[random.Next(0, mix.Length)];
                break;
        }

        return rndStr;
    }
    #endregion

    #region ShowValidationCode
    public void ShowValidationCode(ref int seed, out string validCode, int strLen, int fontSize, int density, RandomStringMode mode, Color clrBg)
    {

        Color[] fontColors = new Color[5] { Color.MediumVioletRed, Color.Black, Color.BlueViolet, Color.LightYellow, Color.Chocolate };
        Pen[] pens = new Pen[5] { Pens.Aquamarine, Pens.White, Pens.YellowGreen, Pens.PaleGoldenrod, Pens.Silver };
        int tmpSeed;
        unchecked
        {
            tmpSeed = (int)(seed * DateTime.Now.Ticks);
            ++seed;
        }
        Random rnd = new Random(tmpSeed);

        string text = GenerateRandomString(strLen, mode);
        validCode = text;
        int height = (int)(Math.Floor((double)(fontSize * 1.5)));

        int width = fontSize * text.Length + fontSize / (text.Length - 2);
        Bitmap bmp = new Bitmap(width, height);
        Brush brush;
        Graphics graphics = Graphics.FromImage(bmp);
        Font font = new Font("Courier New", fontSize, FontStyle.Bold);
        Brush brushBg = new SolidBrush(clrBg);
        graphics.FillRectangle(brushBg, 0, 0, width, height);
        Bitmap tmpBmp = new Bitmap(height, height);
        Graphics tmpGph = null;
        int degree = 40;
        Point tmpPoint = new Point();
        for (int i = 0; i < text.Length; i++)
        {
            int rd = rnd.Next(0, 5);
            brush = new SolidBrush(fontColors[rd]);
            tmpBmp = new Bitmap(height, height);
            tmpGph = Graphics.FromImage(tmpBmp);

            degree = rnd.Next(0, 30);
            if (rnd.Next(0, 2) == 0)
            {
                tmpPoint.X = 2;
                tmpPoint.Y = -1;
            }
            else
            {
                degree = ~degree + 1;
                tmpPoint.X = -2;
                tmpPoint.Y = 1;
            }

            tmpGph.RotateTransform(degree);
            tmpGph.DrawString(text.Substring(i, 1).ToString(), font, brush, tmpPoint);
            graphics.DrawImage(tmpBmp, i * fontSize, 0);
        }
        //for (int j = 0; j < density; j++)
        //{
        //    int pointX = rnd.Next(0, width);
        //    int pointY = rnd.Next(0, height - 1);
        //    int r = rnd.Next(0, 5);
        //    graphics.DrawLine(pens[r], pointX, pointY, pointX, pointY + 1);
        //}


        System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
        try
        {
            if (Request["Type"].ToString().ToLower().Equals("reg"))
            {
                Session["RegValid"] = text;
            }
            else if (Request["Type"].ToString().ToLower().Equals("login"))
            {
                Session["LoginValid"] = text;
            }
            else if (Request["Type"].ToString().ToLower().Equals("culogin"))
            {
                Session["CuLoginValid"] = text;
            }

            bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Gif);
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
            Response.ClearContent();
            Response.ContentType = "image/Gif";
            Response.BinaryWrite(memoryStream.ToArray());
            Response.End();
        }
        catch
        {
        }
        finally
        {
            font.Dispose();

            brushBg.Dispose();
            tmpGph.Dispose();
            tmpBmp.Dispose();
            graphics.Dispose();
            bmp.Dispose();
            memoryStream.Dispose();
        }
    }
    #endregion
}
